// pages/scan/scan.js
// 扫码页面 - 最简化版本
// 扫码结果直接当作小程序页面路径跳转
Page({

  /**
   * 页面的初始数据
   */
  data: {
    isScanning: false
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    // 页面加载时自动开始扫码
    this.startScan();
  },

  /**
   * 开始扫码
   */
  startScan() {
    if (this.data.isScanning) return;
    this.setData({ isScanning: true });

    wx.scanCode({
      onlyFromCamera: true,
      success: async (res) => {
        // 直接处理扫码结果，不显示任何提示
        const handled = await this.handleScanResult(res.path || res.result);
        // 重置扫码状态
        this.setData({ isScanning: false });
        // 如果未处理成功，则返回上一页；若无法返回，则切到首页
        if (!handled) {
          wx.navigateBack({
            fail: () => {
              wx.switchTab({ url: '/pages/index/index' });
            }
          });
        }
      },
      fail: () => {
        // 扫码失败或取消，结束状态并尝试返回上一页；若无法返回则切到首页
        wx.navigateBack({
          success: () => {
            this.setData({ isScanning: false });
          },
          fail: (res) => {
            wx.switchTab({ url: '/pages/index/index' , complete: () => {this.data.isScanning = false;} });
          }
        });
      },
    });
  },

  /**
   * 处理扫码结果
   * 支持：
   * 1) 小程序页面路径（可带查询参数），如：/pages/index/index 或 pages/profile/common-visitors?uid=123
   * 2) http(s) 链接：
   *    - 若存在参数 p/path/page 指向小程序页面，则跳转到该页面
   *    - 否则在内置 WebView 页面打开
   */
  async handleScanResult(result) {
    const raw = (result || '').trim();
    if (!raw) return false;

    // 如果是 http(s) 链接
    if (this.isHttpUrl(raw)) {
      // 优先尝试从 URL 中提取小程序页面路径（支持 p/path/page 等参数）
      const miniPathFromParam = this.extractMiniProgramPathFromUrl(raw);
      if (miniPathFromParam) {
        try {
          await this.directNavigate(miniPathFromParam);
          return true;
        } catch (e) {
          // 继续尝试其他方式提取
        }
      }

      // 次优先：在整个字符串中查找包含 pages/ 的片段
      const miniPathFromAny = this.findMiniProgramPathInString(raw);
      if (miniPathFromAny) {
        try {
          await this.directNavigate(miniPathFromAny);
          return true;
        } catch (e) {
          // 仍然失败则继续走 WebView 兜底
        }
      }

      // 最后兜底：在 WebView 中打开
      try {
        await this.openWebview(raw);
        return true;
      } catch (e) {
        return false;
      }
    }

    // 否则按小程序页面路径处理
    const pagePath = this.normalizeMiniProgramPath(raw);
    if (!pagePath) return false;

    try {
      await this.directNavigate(pagePath);
      return true;
    } catch (e) {
      return false;
    }
  },

  /**
   * 直接导航到小程序页面
   */
  directNavigate(pagePath) {
    return new Promise((resolve, reject) => {
      // 优先使用 redirectTo：替换当前扫描页，避免返回需两次
      wx.redirectTo({
        url: pagePath,
        success: () => resolve(),
        fail: () => {
          // redirectTo 失败（多为目标是 tabBar 页），尝试 switchTab（去掉参数）
          wx.switchTab({
            url: pagePath.split('?')[0],
            success: () => resolve(),
            fail: () => {
              // 兜底再尝试 navigateTo（非 tabBar 场景）
              wx.navigateTo({
                url: pagePath,
                success: () => resolve(),
                fail: () => reject()
              });
            }
          });
        }
      });
    });
  },

  // 判断是否为 http(s) URL
  isHttpUrl(str) {
    return /^https?:\/\//i.test(str);
  },

  // 规范化小程序页面路径：
  // - 去除首尾空格
  // - 补充前导斜杠
  // - 仅当包含 pages/ 段时认为是合法路径
  normalizeMiniProgramPath(str) {
    try {
      const decoded = decodeURIComponent(String(str).trim());
      let path = decoded;
      // 允许不带开头斜杠的写法：pages/xxx/xxx
      if (!path.startsWith('/')) path = '/' + path;
      // 简单校验：必须包含 /pages/
      if (!/\/(pages)\//.test(path)) return '';
      return path;
    } catch (e) {
      return '';
    }
  },

  // 从 http(s) URL 中提取指向小程序页面的路径（支持 p/path/page 参数，大小写不敏感；支持 hash 中的查询）
  extractMiniProgramPathFromUrl(url) {
    try {
      const params = this._parseUrlParams(url);
      const keys = ['p', 'path', 'page', 'pagePath', 'target', 'to', 'route'];
      let candKey = '';
      let cand = '';
      for (const k of keys) {
        const v = params[k] || params[k.toUpperCase()] || params[k.toLowerCase()];
        if (v) { cand = v; candKey = k; break; }
      }
      if (!cand) return '';

      // 如果候选没有自带查询，且 URL 还带有其他参数，则把其余参数拼接到候选后面
      const otherParams = { ...params };
      // 删除候选键（考虑大小写变体）
      delete otherParams[candKey];
      delete otherParams[candKey.toUpperCase()];
      delete otherParams[candKey.toLowerCase()];

      let normalized = this.normalizeMiniProgramPath(cand);
      if (!normalized) return '';

      if (Object.keys(otherParams).length > 0 && normalized.indexOf('?') === -1) {
        const extras = Object.entries(otherParams)
          .filter(([k]) => !!k)
          .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
          .join('&');
        if (extras) normalized += `?${extras}`;
      }
      return normalized;
    } catch (e) {
      return '';
    }
  },

  // 在任意字符串中尝试提取 /pages/... 片段
  findMiniProgramPathInString(str) {
    try {
      const candidates = [];
      const pushIfValid = (s) => {
        const norm = this.normalizeMiniProgramPath(s);
        if (norm) candidates.push(norm);
      };

      const tryStrings = [];
      const raw = String(str);
      tryStrings.push(raw);
      // 尝试解码 1 次
      try {
        tryStrings.push(decodeURIComponent(raw));
      } catch (e) {}
      // 尝试解码 2 次（有时会被双重编码）
      try {
        tryStrings.push(decodeURIComponent(decodeURIComponent(raw)));
      } catch (e) {}

      const regex = /(\/?pages\/[A-Za-z0-9_\-\/]+(?:\?[^#\s]+)?)/g;
      for (const s of tryStrings) {
        let m;
        while ((m = regex.exec(s)) !== null) {
          pushIfValid(m[1]);
        }
        if (candidates.length) break;
      }
      return candidates[0] || '';
    } catch (e) {
      return '';
    }
  },

  // 解析 URL 的查询参数（同时解析 ?query 与 # 后的 query）
  _parseUrlParams(url) {
    const out = {};
    const collect = (queryStr) => {
      if (!queryStr) return;
      queryStr.split('&').forEach(pair => {
        if (!pair) return;
        const [rawK, ...rawVParts] = pair.split('=');
        const k = decodeURIComponent(rawK || '').trim();
        const v = decodeURIComponent(rawVParts.join('=') || '').trim();
        if (!k) return;
        out[k] = v;
      });
    };
    try {
      const s = String(url);
      const qIndex = s.indexOf('?');
      if (qIndex >= 0) {
        const hashIndex = s.indexOf('#', qIndex + 1);
        const queryStr = s.substring(qIndex + 1, hashIndex >= 0 ? hashIndex : undefined);
        collect(queryStr);
      }
      const hashIndex = s.indexOf('#');
      if (hashIndex >= 0) {
        const frag = s.substring(hashIndex + 1);
        // 常见形式：#/path?p=... 或 #?p=...
        const fragQueryIndex = frag.indexOf('?');
        if (fragQueryIndex >= 0) collect(frag.substring(fragQueryIndex + 1));
        else collect(frag);
      }
    } catch (e) {}
    return out;
  },

  // 在内置 WebView 中打开链接
  openWebview(url) {
    return new Promise((resolve, reject) => {
      const encoded = encodeURIComponent(url);
      // 优先使用 redirectTo：替换当前扫描页，避免返回需两次
      wx.redirectTo({
        url: `/pages/webview/webview?url=${encoded}`,
        success: () => resolve(),
        fail: () => {
          // 兜底尝试 navigateTo
          wx.navigateTo({
            url: `/pages/webview/webview?url=${encoded}`,
            success: () => resolve(),
            fail: (err) => reject(err)
          });
        }
      });
    });
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    if (!this.data.isScanning) {
      this.startScan();
    }
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})